﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using Microsoft.Services.Clab.UI.Mvvmc.Presentation.Properties;

namespace Microsoft.Services.Clab.UI.Mvvmc.Presentation
{
    [Serializable]
    public abstract class WpfViewModelBase : ViewModelBase
    {
        internal PropertySyncHelper PropertySyncHelper { get; private set; }

        public WpfViewModelBase()
        {
            this.PropertySyncHelper = new PropertySyncHelper();
            this.CacheMetadata(new WpfViewModelMetadata(this));
        }

        public void RefreshActionCommands()
        {
            CommandManager.InvalidateRequerySuggested();
        }

        protected internal void MapRoutedCommandToAction(IView view, RoutedCommand command, string actionName)
        {
            if (view == null)
            {
                throw new ArgumentNullException("view");
            }

            var viewWpf = view as UIElement;
            if (viewWpf == null)
            {
                throw new ArgumentException(Resources.ViewMustBeWpfUIElement, "view");
            }

            viewWpf.CommandBindings.Add(
                new CommandBinding(
                    command,
                    (s, e) => this.Controller.DoAction(actionName, e.Parameter),
                    (s, e) => e.CanExecute = this.Controller.CanDoAction(actionName, e.Parameter)));

        }

        protected sealed override void CacheMetadata(ViewModelMetadata metadata)
        {
            base.CacheMetadata(metadata);
        }

        protected virtual void CacheMetadata(WpfViewModelMetadata metadata)
        {
        }

        protected override void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            base.OnPropertyChanged(e);
            if (this.PropertySyncHelper != null)
            {
                this.PropertySyncHelper.UpdateViewDependencyProperty(this, e.PropertyName, this.Views);
            }
        }
    }
}